<template>
  <el-form :model="form" label-width="80px" inline>
    <el-form-item label="出发地: ">
      <el-autocomplete
        v-model="form.fromStation"
        placeholder="请输入出发地"
        :fetch-suggestions="(val, cb) => remoteMethod(val, cb, 'fromStation')"
        @select="($event) => handlSelect($event, 'fromStation')"
        @focus="($event) => handleFocus($event, 'fromStation')"
      />
    </el-form-item>

    <el-form-item>
      <Sort size="20" class="sort-icon" @click="handleExchange" />
    </el-form-item>

    <el-form-item label="目的地: ">
      <el-autocomplete
        v-model="form.toStation"
        placeholder="请输入目的地"
        :fetch-suggestions="(val, cb) => remoteMethod(val, cb, 'toStation')"
        @select="($event) => handlSelect($event, 'toStation')"
        @focus="($event) => handleFocus($event, 'toStation')"
      />
    </el-form-item>

    <el-form-item label="出发日: ">
      <el-date-picker
        v-model="form.trainDate"
        type="date"
        placeholder="选择日期"
        value-format="YYYY-MM-DD"
        :disabled-date="handleDisabledDate"
        @change="() => handleSearch()"
      ></el-date-picker>
    </el-form-item>

    <el-form-item>
      <el-button type="primary" class="search-btn" @click="handleSearch()"
        >查询</el-button
      >
    </el-form-item>
  </el-form>

  <h6>
    {{ tips }}
  </h6>

  <el-table
    class="table-container"
    :data="tableData"
    style="width: 100%"
    @expand-change="handleExpandChange"
    ref="tableRef"
    row-key="train_no"
  >
    <!-- 经停站 -->
    <el-table-column #default="{ row }" type="expand">
      <div class="flex-center mgl-20">
        <!-- '上车补票'方案总数 -->
        <div>{{ `${row.replacePlanRateNum} / ${row.replacePlanNum}` }}</div>
        <!-- 查询'上车补票'方案进度条 -->
        <el-progress
          class="progress"
          :text-inside="true"
          :stroke-width="20"
          :percentage="row.percentage || 0"
        ></el-progress>

        <div>{{ row.train_no }}</div>
        <!-- 经停站列表 -->
        <div class="stopover-container">
          <div
            class="item"
            v-for="(item, index) in row.stopoverStationList"
            :key="index"
          >
            <div>{{ item.index }} {{ item.station_name }}</div>
            <div>{{ item.arrive_time }}</div>
          </div>
        </div>
      </div>

      <!-- 排序方式 -->
      <!-- 只有当起始站与终点站都为中间站时,才出现排序 -->
      <!-- <el-switch
        v-if="
          row['出发车站类型'] === '过' &&
          row['到达车站类型'] === '过' &&
          row.replacePlanList.length
        "
        v-model="row.replacePlanSort"
        active-text="力"
        inactive-text="钱"
        class="mgl-20"
        @change="(val) => handleChangeReplacePlanSort(val, row)"
      ></el-switch> -->
      <div
        v-for="(item, index) in row.replacePlanList"
        :key="index"
        class="replace-plan-container mgl-20"
      >
        <span>{{ index + 1 }}</span>
        <span>{{ `${item["出发车站"]} ${item["出发时间"]}` }}</span>
        <span>{{ `${item["到达车站"]} ${item["到达时间"]}` }}</span>
        <span>{{ `历时: ${item["历时"]}` }}</span>
        <span v-if="item['二等座']">{{ `二等座: ${item["二等座"]}` }}</span>
        <span v-if="item['无座']">{{ `无座: ${item["无座"]}` }}</span>
        <span v-if="item['一等座']">{{ `一等座: ${item["一等座"]}` }}</span>
        <span v-if="item['商务座']">{{ `商务座: ${item["商务座"]}` }}</span>
        <span v-if="item['硬卧']">{{ `硬卧: ${item["硬卧"]}` }}</span>
        <span v-if="item['动卧']">{{ `动卧: ${item["动卧"]}` }}</span>
        <span v-if="item['软卧']">{{ `软卧: ${item["软卧"]}` }}</span>
        <span v-if="item['高级软卧']">{{
          `高级软卧: ${item["高级软卧"]}`
        }}</span>
        <span v-if="item['硬座']">{{ `硬座: ${item["硬座"]}` }}</span>
        <span v-if="item['软座']">{{ `软座: ${item["软座"]}` }}</span>
      </div>
    </el-table-column>

    <el-table-column
      v-for="(column, index) in tableColumn"
      :key="index"
      :prop="column.prop"
      :label="column.label"
      :width="column.width"
    >
      <template v-if="column.prop === '出发时间'" v-slot="{ row }">
        {{ `${row["出发车站"]} ${row["出发时间"]}` }}
        <span class="gray">{{ ` (${row["出发车站类型"]})` }}</span>
      </template>

      <template v-else-if="column.prop === '到达时间'" v-slot="{ row }">
        {{ `${row["到达车站"]} ${row["到达时间"]}` }}
        <span class="gray">{{ ` (${row["到达车站类型"]})` }}</span>
      </template>
    </el-table-column>
  </el-table>
</template>

<script setup>
import { computed, onMounted, reactive, ref } from "vue";
import { getTrainList, getTrainNoList } from "./service/api";
import { Sort } from "@element-plus/icons";
import defaultStationConfig from "./utils/stationConfig";
import { filterDate } from "./utils";

const form = reactive({
  fromStation: "",
  toStation: "",
  trainDate: "",
});

const tableData = ref([]);

const seatCategoryList = [
  "二等座",
  "无座",
  "一等座",
  "商务座",
  "硬卧",
  "动卧",
  "软卧",
  "高级软卧",
  "硬座",
  "软座",
];

const tableColumn = computed(() => {
  const defaultColumn = [
    {
      prop: "车次",
      label: "车次",
    },
    {
      prop: "出发时间",
      label: "出发",
      width: 160,
    },
    {
      prop: "到达时间",
      label: "到达",
      width: 160,
    },
    {
      prop: "历时",
      label: "历时",
    },
  ];

  const seatCategoryColumn = seatCategoryList.map((item) => {
    return {
      prop: item,
      label: item,
    };
  });

  return defaultColumn.concat(seatCategoryColumn);
});

onMounted(async () => {
  let { fromStation, toStation, trainDate } =
    JSON.parse(localStorage.getItem("formInline")) || {};
  const currentDate = new Date();
  const givenDate = new Date(trainDate);
  // 将日期部分设置为0，只比较年月日
  currentDate.setHours(0, 0, 0, 0);
  givenDate.setHours(0, 0, 0, 0);
  const finalCurrentDate = currentDate.getTime();
  const finalGivenDate = givenDate.getTime();

  form.fromStation = fromStation || "";
  form.toStation = toStation || "";
  // 判断缓存日期是否小于当天,小于则自动更新为当日日期
  form.trainDate =
    finalGivenDate >= finalCurrentDate ? trainDate : filterDate(currentDate);

  handleSearch();
});

const remoteMethod = (val, cb) => {
  // 模糊搜索
  if (val !== "") {
    const lowVal = val.toLowerCase();
    let tempList = [];
    for (let i in defaultStationConfig) {
      const { label, pinyin, simplePinyin } = defaultStationConfig[i];
      const target =
        label.toLowerCase().indexOf(lowVal) > -1 ||
        pinyin.toLowerCase().indexOf(lowVal) > -1 ||
        simplePinyin.toLowerCase().indexOf(lowVal) > -1;
      if (target) {
        tempList.push({
          value: defaultStationConfig[i].label,
        });
      }
    }
    cb(tempList);
    handleSearch();
  } else {
    // 没有输入值时,显示搜索历史列表
    cb(handleFocus());
  }
};

const handleFocus = () => {
  const restaurants = JSON.parse(localStorage.getItem("restaurants"));
  if (!restaurants) return [];
  return restaurants.map((item) => {
    return { value: item, label: item };
  });
};

const handleExchange = () => {
  [form.fromStation, form.toStation] = [form.toStation, form.fromStation];
  handleSearch();
};

const tips = ref("");
const handleSearch = async (params = {}) => {
  let { fromStation = "", toStation = "", target = false } = params;
  fromStation = fromStation || form.fromStation;
  toStation = toStation || form.toStation;

  let { trainDate } = form;
  if (!fromStation || !toStation || !trainDate) return;
  const fromValue = defaultStationConfig[fromStation];
  const toValue = defaultStationConfig[toStation];
  if (!fromValue || !toValue) return;

  const res = await getTrainList({
    trainDate,
    fromStation: defaultStationConfig[fromStation].value,
    toStation: defaultStationConfig[toStation].value,
    purposeCodes: "ADULT",
  });

  if (target) {
    return Promise.resolve(res);
  }

  console.warn('marp', res)

  tableData.value = [];
  tips.value = `${fromStation} --> ${toStation} (${trainDate} ${handleGetWeek(
    trainDate
  )}) 共计${res.length}个车次`;
  tableData.value = res.map((item) => {
    item.stopoverStationList = []; // 存放经停站信息
    item.replacePlanNum = 0; // '上车补票'方案总数
    item.replacePlanRateNum = 0; // 查询'上车补票'方案进度
    item.replacePlanList = []; // 查询'上车补票'方案列表
    item.percentage = 0; // 进度条
    item.replacePlanSort = true; // '上车补票'排序方式, 默认 '力'(站票)排序
    return item;
  });

  // 缓存搜索列表
  const restaurants = JSON.parse(localStorage.getItem("restaurants")) || [];
  let hasRecord = false;
  hasRecord = restaurants.some((item) => {
    const currentItem = item.split("-");
    return currentItem[0] === fromStation && currentItem[1] === toStation;
  });
  if (!hasRecord) {
    restaurants.unshift(`${fromStation}-${toStation}`);
    localStorage.setItem("restaurants", JSON.stringify(restaurants));
  }

  // 缓存当前查询条件,以供下次进入页面使用此数据
  localStorage.setItem("formInline", JSON.stringify(form));
};

const handlSelect = ({ value }, type) => {
  if (value.indexOf("-") > -1) {
    const arr = value.split("-");
    form.fromStation = arr[0];
    form.toStation = arr[1];
  } else {
    form[type] = value;
  }

  handleSearch();
};

const handleDisabledDate = (time) => {
  // 获取今天的时间
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  // 将所选时间转换为时间戳
  const selectedTimestamp = time.getTime();
  // 只允许选择今天及以后的时间
  return selectedTimestamp < today.getTime();
};

const handleGetWeek = (dateString) => {
  const daysOfWeek = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
  const date = new Date(dateString);
  const dayOfWeek = date.getDay();
  return daysOfWeek[dayOfWeek];
};

const tableRef = ref(null);
const handleExpandChange = async (row, expandedRows) => {
  const { train_no, stopoverStationList } = row;
  if (expandedRows.length && !stopoverStationList.length) {
    // 获取经停站信息
    const res = await getTrainNoList({
      trainNo: train_no,
      fromStation: defaultStationConfig[row["出发车站"]]
        ? defaultStationConfig[row["出发车站"]].value
        : "",
      toStation: defaultStationConfig[row["到达车站"]]
        ? defaultStationConfig[row["到达车站"]].value
        : "",
      trainDate: form.trainDate,
    });

    let stopoverStationList = [];
    res.forEach(({ station_name, arrive_time }, index) => {
      const obj = {
        station_name,
        index: index + 1,
        arrive_time,
      };
      // 经停站列表
      stopoverStationList.push(obj);
    });

    row.stopoverStationList = stopoverStationList;
    /**
     * 第二种方案:
     * 可以在这里先把所有方案列出,再循环请求接口 TODO
     */

    // let tempList = [];

    let startStationIndex = -1, // 起始站 index
      endStationIndex = -1; // 结束站 index
    stopoverStationList.forEach((item, index) => {
      item.station_name === row["出发车站"] && (startStationIndex = index);
      item.station_name === row["到达车站"] && (endStationIndex = index);
    });

    row.replacePlanNum =
      (startStationIndex + 1) *
      (stopoverStationList.length - 1 - startStationIndex); // '上车补票'方案总数

    let replacePlanRateNum = 0,
      replacePlanList = [],
      start = startStationIndex; // 从起始站开始找

    while (start > -1) {
      // 终止站为起始站+1(起始站的后一个站)
      // let end = startStationIndex + 1;

      // 从终止站开始查询
      let end = endStationIndex; // 从最大区间开始找(可以多坐几个站)

      let startStationName = "",
        endStationName = "",
        tempEnd = endStationIndex;

      startStationName = stopoverStationList[start]
        ? stopoverStationList[start].station_name
        : "";
      let target = true; // 循环结束标志
      let isPreLoop = true; // 往前循环标志

      while (target) {
        endStationName = stopoverStationList[end]
          ? stopoverStationList[end].station_name
          : "";

        // 查询 上车补票 列表
        const res = await handleSearch({
          fromStation: startStationName,
          toStation: endStationName,
          target: true,
        });
        // 找到同一趟车次
        const templist = res.filter((item) => item.train_no === train_no);
        replacePlanList.push(...templist);

        row.replacePlanList = replacePlanList.reduce((sum, item) => {
          const hasRecord = sum.some(
            (obj) =>
              // 去重
              obj["出发车站"] === item["出发车站"] &&
              obj["到达车站"] === item["到达车站"]
          );

          // 去除没有坐席的车次(只显示有车票的车次)
          const hasSeat = seatCategoryList.some(
            (i) => item[i] !== "" && item[i] !== "无"
          );
          // const hasSeat = true; // 测试

          if (!hasRecord && hasSeat) {
            const obj = {};
            for (let i in item) {
              item[i] !== "" && item[i] !== "无" && (obj[i] = item[i]);
            }
            sum.push(obj);
          }
          return sum;
        }, []);

        // 查询进度
        replacePlanRateNum++;
        row.replacePlanRateNum = replacePlanRateNum;
        // 进度条
        if (row.percentage > 100) {
          row.percentage = 0;
        }
        // 四舍五入并保留整数部分
        row.percentage = parseInt(
          (replacePlanRateNum / row.replacePlanNum) * 100
        ).toFixed(0);

        /**
         * 1, 先从终点站开始,依次往前,到起始站的后一个站结束;
         * 2, 若终点站不为经停站的终点站,开始向终点站的后面查询,将end设置为查询终点站的后一个站开始,依次往后,直到经停站的末尾结束
         */
        // 从终点站开始往前查询
        if (end <= endStationIndex) {
          end--;
        }

        // 往前查询结束标志
        if (end <= startStationIndex) {
          target = false;
          isPreLoop = false; // 结束往前查询
        }

        // 从终点站开始往后查询
        if (!isPreLoop && endStationIndex !== stopoverStationList.length - 1) {
          tempEnd++;
          end = tempEnd;
          target = true;
          // 往后查询结束标志
          if (end > stopoverStationList.length - 1) {
            target = false;
          }
        }
      }
      start--;
    }
  }
};

// const handleChangeReplacePlanSort = (val, row) => {
//   /**
//    * 力:
//    * 选择力,说明想 上车补票, 可以先从起始站开始,找到终点站,
//    * 钱:
//    * 将replacePlanList数据从
//    */
//   console.log("val", val, row);
// };
</script>

<style lang="less" scoped>
.flex {
  display: flex;
}
.flex-center {
  .flex();
  align-items: center;
}

.gray {
  color: #999;
}

.sort-icon {
  color: #333;
  width: 20px;
  cursor: pointer;
}
.table-container {
  margin-top: 40px;
}

.stopover-container {
  display: flex;
  flex: 1;
  overflow-y: scroll;

  .item {
    margin-right: 15px;
    flex-shrink: 0;
  }
}
.replace-plan-container {
  margin: 15px 0;
  span {
    padding-right: 30px;
  }
}
.mgl-20 {
  margin-left: 20px;
}
.progress {
  margin: 0 80px;
  width: 120px;
}
</style>
